package com.hitqz.robot.biz.controller;

import cn.hutool.core.util.StrUtil;
import com.google.common.cache.Cache;
import com.hitqz.robot.common.core.util.R;
import com.hitqz.robot.biz.websocket.endpoint.LiveEndpoint;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.io.InputStream;
import java.nio.ByteBuffer;

/**
 * 推流
 *
 * @author wengyongxin
 * @date 2024-05-26 09:21:06
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/rtsp" )
@Tag(description = "rtsp" , name = "视频流管理" )
@Slf4j
public class RtspController {


	private  final Cache<String, Boolean> videoStreamOutputAlive;

	@RequestMapping(value = "/ws" )
	@ResponseBody
	public void receive(HttpServletRequest request){
		String sourceKey = request.getParameter("sourceKey");
		if (StrUtil.isBlank(sourceKey)){
			log.error("[http]sourceKey is blank");
			return;
		}
		try {
			log.info("[http]sourceKey:{},output received start",sourceKey);
			@Cleanup
			InputStream inputStream = request.getInputStream();
			ByteBuffer buffer = ByteBuffer.allocateDirect(4096); // 分配直接缓冲区
			byte[] byteArray = new byte[4096];  // 创建临时字节数组用于读取数据
			int length;
			while (true) {
				// 如果流断掉且剩余的数据不足byteArray,此处会阻塞;
				// 不过,videoStreamOutputAlive的标志有过期时间,推流判断线程会重启推流，这边的阻塞就会抛异常退出了
				length = inputStream.read(byteArray);
				if (length == -1) {
					log.info("[http]sourceKey:{},output received end",sourceKey);
					break; // 流结束，退出循环
				}
				if (length > 0) {
					buffer.clear();  // 清空缓冲区准备写入数据
					buffer.put(byteArray, 0, length);  // 将数据放入 ByteBuffer
					buffer.flip();  // 切换到读模式
					LiveEndpoint.sendVideoData(sourceKey, buffer);
				}
				videoStreamOutputAlive.put(sourceKey,true);
			}
			log.info("[http]sourceKey:{},output received over,steam dead",sourceKey);
			videoStreamOutputAlive.put(sourceKey,false);
		}catch (Exception e){
			log.error("[http]sourceKey:{},output received error,{}",sourceKey,e.getMessage());
			videoStreamOutputAlive.put(sourceKey,false);
		}

	}

}